package com.hxl.alert.utils;

import com.hxl.alert.entity.AlertOriginBase;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtils {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    //扫描
    public long countKeysWithPrefix(String prefix) {
        // 前缀为空时，直接返回0
        if (prefix == null || prefix.isEmpty()) {
            return 0;
        }

        ScanOptions scanOptions = ScanOptions.scanOptions().match(prefix + "*").build();
        // 执行 Redis 操作并检查返回值
        Long count = redisTemplate.execute((RedisCallback<Long>) connection -> {

            long result = 0;
            try (Cursor<byte[]> cursor = connection.scan(scanOptions)) {
                while (cursor.hasNext()) {
                    cursor.next();
                    result++;
                }
            } catch (Exception e) {
                // 捕获异常并打印错误日志，返回0
                e.printStackTrace();
            }
            return result;
        });

        // 如果返回结果为 null，返回0
        return count != null ? count : 0;
    }

    // 通用的 ZCOUNT 方法
    public Long countByScoreRange(String zSetKey, double minScore, double maxScore) {
        // 执行 ZCOUNT 操作，返回指定分数范围内的元素数量
        return redisTemplate.execute((RedisCallback<Long>) connection -> {
            ZSetOperations<String, Object> zSetOps = redisTemplate.opsForZSet();
            return zSetOps.count(zSetKey, minScore, maxScore);
        });
    }

    /**
     * 是否存在key
     *
     * @param key
     * @return
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 添加元素,有序集合是按照元素的score值由小到大排列
     *
     * @param key
     * @param value
     * @param score
     * @return
     */
    public Boolean zAdd(String key, String value, double score) {
        return redisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     * @param key
     * @param values
     * @return
     */
    public void zRemove(String key, Object... values) {
         redisTemplate.opsForZSet().remove(key, values);
    }

    /**
     * 设置指定 key 的值
     *
     * @param key
     * @param value
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 获取指定 key 的值
     *
     * @param key
     * @return
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 只有在 key 不存在时设置 key 的值
     *
     * @param key
     * @param value
     * @return 之前已经存在返回false, 不存在返回true
     */
    public Boolean setIfAbsent(String key, Object value, long l, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, l, timeUnit);
    }

    /**
     * 删除key
     *
     * @param key
     */
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    /**
     * @param key
     * @param value
     * @return
     */
    public void lRightPush(String key, Object value) {
        redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 设置过期时间
     *
     * @param key
     * @param timeout
     * @param unit
     * @return
     */
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 根据Score值查询集合元素
     *
     * @param key
     * @param min 最小值
     * @param max 最大值
     * @return
     */
    public Set<Object> zRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }
}
